package com.gaogzhen.designPattern.twoPhraseTermination;

/**
 * @author Administrator
 * @version 1.0
 * @description
 * @date 2022-10-06 09:24
 */
public abstract class AbstractTerminatableThread extends Thread implements Terminatable{
    /**
     * 模式角色
     */
    public final TerminationToken terminationToken;

    public AbstractTerminatableThread() {
        this(new TerminationToken());
    }

    public AbstractTerminatableThread(TerminationToken terminationToken) {
        super();
        this.terminationToken = terminationToken;
        terminationToken.register(this);
    }

    /**
     * 子类线程停止后清理工作
     */
    protected void doCleanUp(Exception e) {}

    /**
     * 子类实现线程处理逻辑
     * @throws Exception   异常
     */
    protected abstract void doRun() throws Exception;

    /**
     * 子类用于执行线程停止所做的工作
     */
    protected void doTerminate() {}

    @Override
    public void run() {
        Exception ep = null;
        try {
            for (;;) {
                // 检测线程停止标志
                if (terminationToken.isShutdown && terminationToken.reservations.get() <= 0) { break;}
                doRun();
            }
        } catch (Exception e) {
            ep = e;
        } finally {
            try {
                doCleanUp(ep);
            }finally {
                terminationToken.notifyThreadTermination(this);
            }
        }
    }

    @Override
    public void interrupt() {
        terminate();
    }

    @Override
    public void terminate() {
        terminationToken.setShutdown(true);
        try {
            doTerminate();
        } finally {
            // 若无待处理的任务，则尝试强制终止线程
            if (terminationToken.reservations.get() <= 0) { super.interrupt(); }

        }
    }

    public void terminate(boolean waitUntilThreadTerminated) {
        terminate();
        if (waitUntilThreadTerminated) {
            try {
                this.join();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}
